namespace SimpleWebServices.Web.UI
{
    using System;
    using System.Net;
    using System.Web;
    using System.Web.UI;
    using Moq;
    using Xunit;

    public sealed class DefaultPageFacts
    {
        [Fact]
        public void typedef()
        {
            Assert.True(new ObjectExpectations<DefaultPage>()
                .DerivesFrom<Page>()
                .IsConcreteClass()
                .IsUnsealed()
                .HasDefaultConstructor()
                .Result);
        }

        [Fact]
        public void ctor()
        {
            Assert.NotNull(new DefaultPage());
        }

        [Fact]
        public void ctor_string()
        {
            Assert.NotNull(new DefaultPage("test"));
        }

        [Fact]
        public void ctor_stringEmpty()
        {
            Assert.Throws<ArgumentOutOfRangeException>(() => new DefaultPage(string.Empty));
        }

        [Fact]
        public void ctor_stringNull()
        {
            Assert.Throws<ArgumentNullException>(() => new DefaultPage(null));
        }

        [Fact]
        public void prop_Location_get()
        {
            try
            {
                Uri url = new Uri("http://example.com");

                var mock = new Mock<HttpContextBase>();
                mock.SetupGet<Uri>(x => x.Request.Url).Returns(url).Verifiable();
                HttpContextFactory.Mock = mock.Object;

                string expected = "http://example.com/test";
                string actual = new DefaultPage("test").Location;

                Assert.Equal<string>(expected, actual);

                mock.VerifyAll();
            }
            finally
            {
                HttpContextFactory.Reset();
            }
        }

        [Fact]
        public void prop_Path()
        {
            Assert.True(new PropertyExpectations(typeof(DefaultPage).GetProperty("Path"))
                .DefaultValueIs(new Uri("home", UriKind.Relative))
                .ArgumentNullException()
                .ArgumentOutOfRangeException(new Uri("http://example.com"))
                .IsNotDecorated()
                .Set(new Uri("path", UriKind.Relative))
                .Result);
        }

        [Fact]
        public void op_Page_Load()
        {
            try
            {
                Uri url = new Uri("http://example.com");

                var mock = new Mock<HttpContextBase>();
                mock.SetupGet<Uri>(x => x.Request.Url).Returns(url).Verifiable();
                mock.Setup(x => x.Response.Cache.SetCacheability(HttpCacheability.Public)).Verifiable();
                mock.Setup(x => x.Response.Cache.SetExpires(It.IsAny<DateTime>())).Verifiable();
                mock.SetupSet(x => x.Response.StatusCode).Callback(expected => Assert.Equal<int>((int)HttpStatusCode.SeeOther, expected)).Verifiable();
                mock.Setup(x => x.Response.AppendHeader("Location", "http://example.com/home")).Verifiable();
                mock.SetupSet(x => x.Response.ContentType).Callback(expected => Assert.Equal<string>("text/html", expected)).Verifiable();
                HttpContextFactory.Mock = mock.Object;

                new DefaultPage().Page_Load(null, new EventArgs());

                mock.VerifyAll();
            }
            finally
            {
                HttpContextFactory.Reset();
            }
        }
    }
}